home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- ;*******************************************************************************
- ;* *
- ;* SYNC?/ASYNCHRONOUS COMMUNICATIONS FOR THE TI-PROFESSIONAL COMPUTER *
- ;* REV LEVEL 1.0 *
- ;* WRITTEN AND PLACED IN THE PUBLIC DOMAIN BY: *
- ;* *
- ;* DAN MAUS *
- ;* 16737 ANNA TRAIL S.E. *
- ;* PRIOR LAKE, MN 55372 *
- ;* *
- ;* MANY THANKS TO: TEXAS INSTRUMENTS, EDEN PRAIRIE MN. *
- ;* ARROW ELECTRONICS, EDINA MN. *
- ;* COMPUTER LAW SYSTEMS, EDEN PRAIRIE MN. *
- ;* *
- ;* You can find Dan Maus and other programmers on Terrapin Station dBBS! *
- ;* 612/623-0152 24 hours - 2400/1200 *
- ;*******************************************************************************
- CODE SEGMENT PUBLIC
- ASSUME CS:CODE,DS:CODE,ES:CODE
- JMP START
- ; SOME EQUATES AND USAGE CONVENTIONS
-
- SVCINT EQU 70H ; INTERRUPT USED BY APPLICATION
- ; FUNC
- ; NOTE ONLY PORT1 IS CURRENTLY SUPPORTED
- ; AH = 1 - OPEN/CHANGE COMMUNICATIONS
- ; AL = PORT (1-4)
- ; CURRENTLY PARAMETERS ARE STORED
- ; IN THIS ROUTINE, HOWEVER A FUTURE
- ; ENHANCEMENT WILL ALLOW EXTERNAL TABLES
- ;
- ;
- ; STATUS RETURNED IN AL
- ; 0 = PORT OPENED
- ; -1 = NON EXISTENT PORT, OR HARDWARE
- ; INCOMPATIBILITY.
- ;
- ; AH = 2 READ COMMUNICATION STATUS
- ; AL = PORT (1-4)
- ; STATUS RETURNED IN AL
- ; 0 = READY <->
- ; 1 = DATA IN RECV BUFFER
- ; 2 = RECV BUFFER OVERFLOW
- ;
- ; AH = 3 READ CHARACTER FROM FIFO BUFFER
- ; AL = PORT
- ; CHAR RETURNED IN AL
- ; CHECK FNC 2 BEFORE CALLING
- ; RETURNS 0 IF NO CHAR READY
- ;
- ; AH = 4 WRITE CHARACTER
- ; AL = PORT
- ; DL = CHAR
- ;
- ; AH = 5 ISSUE BREAK
- ; AL = PORT
- ;
- ; AH = 6 CLOSE COMMUNICATIONS
- ; AL = PORT
- ;
- ; AH = 7 PURGE INPUT BUFFER
- ; AL = PORT
- ;
-
- ;
- COMINT EQU 40H ; 8530 INTERRUPT
- ; GENERATED BY ASYNC BOARD.
- ; DO NOT USE THIS FROM AN APPLICATION.
- ;
- PARTBL: ; OPEN COMMUNICATIONS STRUCTURE
- ; ASYNC BAUD RATES BASED ON 4.9152 MHZ CLOCK
- BR300 EQU 54
- BR1200 EQU 62
- BR2400 EQU 30
- BR4800 EQU 14
- BR9600 EQU 6
- BR192 EQU 2
-
- BAUDR DW BR9600 ; BAUD RATE BYTE NOTE:USED IN BYTES (H/L)
- ; WHEN SENT TO 8530
- RBITS DB 8 ; NUMBER OF READ DATA BITS (5-8)
- TBITS DB 8 ; NUMBER OF WRITE DATA BITS (5-8)
- SBITS DB 1 ; NUMBER OF STOP BITS 0 = SYNCRONOUS OPERATION
- ; (SEE 8530 TECH SPECS)
- ; 1 = 1 BIT
- ; 2 = 1-1/2 BITS
- ; 3 = 2 BITS
- PBITS DB 0 ; PARITY 0 = NO, 1 = EVEN, 3 = ODD
- TESTRES: ; OFFSET CHECKED TO VALIDATE RESIDENCY
- NPORTS EQU 1 ; NUMBER OF PORTS IN SYSTEM
- RXINTEN EQU 20H ; ENABLE INTERRUPT ON NEXT RX CHAR (WR0)
- BREAK EQU 10H ; ENABLE BREAK SIGNAL (WR5)
- RESET EQU 0C0H ; RESET 8530
- COMNLEN EQU 80H ; COMMAND LINE PARAMETER LENGTH
- ;*********************** DATA AREA ****************************
- SVCOLD DD ; OLD INTERRUPT VECTOR FOR COM SVC
- COMOLD DD ; " " " " 8530 INTERRUPT
-
- CINT DW 0
- ACOM DW 0
- ADAT DW 0
- BCOM DW 0
- INADR DW 0 ; CURRENT BUFFER ADDRESS USED BY 8530 ISR
- SVADR DW 0 ; CURRENT BUFFER ADR USED BY SVC ROUTINE
- BUFCNT DW 0 ; CURRENT BYTE COUNT IN BUFFER
- TXREG DB 0
-
- ;************************** SVC INTERRUPT SERVICE ROUTINE ********************
- ;
- SVCISR:
- STI ; IMMEDIATELY REENABLE INTERRUPTS
- PUSH AX ; NOTE APPLICATION MUST SUPPLY SUFFICIENT STACK
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH CS
- POP DS ; SET UP OUR CS AS OUR DS
- CMP AH,7
- JG INVFC
- CMP AH,1
- JL INVFC
- PORTS: ; SET UP CORRECT PORT IDS (CINT ACOM ADAT BCOM)
- CMP AL,NPORTS
- JG BADPRT
- DEC AL
- JC INVPORT
- SHL AL,1
- SHL AL,1
- SHL AL,1
- PUSH AX
- XOR AH,AH
- PORT1 EQU 0E0H
- ADD AL,PORT1
- MOV CINT,AX ; SAVE INTERRUPT ACKNOWLEDGE PORT
- ADD AL,4
- MOV BCOM,AX ; SAVE CHANNEL B COMMAND PORT
- INC AL
- INC AL ; SKIP CHANNEL B DATA (UNUSED)
- MOV ACOM,AX ; SAVE CHANNEL A COMMAND PORT
- INC AL
- MOV ADAT,AX ; SAVE CHANNEL A DATA PORT
- POP AX
- XOR AL,AL
- XCHG AH,AL
- MOV SI,AX
- SHL SI,1
- JMP WORD PTR CS:[JTBL+SI]
- JTBL DW 0 ; DUMY
- DW OPEN
- DW STAT
- DW READ
- DW WRITE
- DW BRAAK
- DW CLOSE
- DW PURGE
- INVFC:
- INVPORT:
- BADPRT:
- MOV AX,-1 ; SET BAD STATUS & RETURN
- COMEXIT: ; SVC CALL EXIT
- PUSH ES
- POP DS
- POP DI
- POP SI
- POP DX
- POP CX
- POP BX
- POP [TRASH] ; DISCARD OLD AX, KEEP OURS
- IRET ; RETURN TO SVC CALLER
- TRASH DW 0
- ;************************* OPEN PORT ***************************
- OPEN: ; OPEN COMMUNICATION PORT IN AL
- MOV DX,ACOM ; LOAD A COMMAND PORT
- MOV AL,9 ; SELECT WR 9
- OUT DX,AL
- MOV AL,RESET ; RESET 8530
- OUT DX,AL
- MOV AL,11 ; SELECT WR 11
- OUT DX,AL
- WR11CTL EQU 52H ; SET RX CLOCK=BR GENERATOR
- ; SET TX CLOCK=BR GENERATOR
- MOV AL,WR11CTL
- OUT DX,AL
- MOV AL,14 ; ENABLE BR GENERATOR
- OUT DX,AL
- MOV AL,3
- OUT DX,AL
- MOV AL,12 ; SEL WR 12
- OUT DX,AL
- MOV AL,BYTE PTR[BAUDR] ; OUTPUT LOW ORDER BAUD RATE
- OUT DX,AL
- MOV AL,13 ; SEL WR 13
- OUT DX,AL
- MOV AL,BYTE PTR[BAUDR+1] ; OUTPUT HIGH ORDER BYTE
- OUT DX,AL
- MOV AL,2 ; WR2 VECTOR REGISTER
- OUT DX,AL
- MOV AL,COMINT
- OUT DX,AL ; SET 8530 INTERRUPT VECTOR
- MOV AL,15 ; WR15
- OUT DX,AL
- MOV AL,0 ; NO EXTERNAL STATUS INTERRUPTS
- OUT DX,AL ;
- MOV AL,1 ; WR1
- OUT DX,AL
- MOV AL,10H ; INT ON ALL RX CHARS & SP COND
- OUT DX,AL
- MOV AL,5 ; WR 5
- OUT DX,AL
- XOR AX,AX
- MOV AL,TBITS
- SUB AL,5 ;
- ROR AX,1
- ROR AL,1
- ROR AL,1 ; SWAP 2 BITS SEE 8530 TR
- ROL AX,1
- ROR AL,1
- ROR AL,1 ; POSITION TX BITS
- OR AL,8AH ; ENABLE DTR RTS TX
- MOV TXREG,AL
- OUT DX,AL
- MOV AL,3 ; WR3
- OUT DX,AL
- XOR AX,AX
- MOV AL,RBITS ; SET RECIEVE BITS ENABLE RECIEVE
- SUB AL,5
- ROR AX,1
- ROR AL,1
- ROR AL,1
- ROL AX,1
- ROR AL,1
- OR AL,1 ; SET RX ENABLE
- OUT DX,AL
- MOV AL,4
- OUT DX,AL
- MOV AL,SBITS
- SHL AL,1
- SHL AL,1
- OR AL,PBITS ; SET PARITY BITS
- OR AL,40H ; SET X16 CLOCK MODE
- OUT DX,AL
- MOV DX,BCOM ; B COMMAND PORT
- MOV AL,15
- OUT DX,AL
- MOV AL,0 ; NO EXT STS INT'S
- OUT DX,AL
- MOV AL,1
- OUT DX,AL
- MOV AL,10H ; INT ON ALL RX CHAR
- OUT DX,AL ; PORT IS NOW OPEN
- MOV AX,OFFSET INBUF
- MOV SVADR,AX
- MOV INADR,AX
- XOR AX,AX
- MOV BUFCNT,AX
- MOV DX,ACOM
- MOV AL,9
- OUT DX,AL
- MOV AL,8H ; ENABLE RECIEVE INTERRUPTS
- OUT DX,AL
- MOV DX,BCOM
- MOV AL,9
- OUT DX,AL
- MOV AL,8H
- OUT DX,AL
- MOV AL,36H
- OUT 19H,AL ; SET 8259 ENABLE COM1
- JMP COMEXIT
- ;************************ STATUS ROUTINE ********************
- STAT:
- XOR AX,AX
- MOV CX,BUFCNT
- JCXZ SDONE
- MOV AL,1 ; SET DATA IN BUFFER
- CMP CX,0
- JG SDONE
- INC AL ; IF DATALEN < 0 THEN BUF OVERFLOW
- SDONE: JMP COMEXIT
- ;*********************** OBTAIN CHAR FROM CIRC BUFFER **************
- ;
- ; NOTE: READ BUFFER STRATEGY MUST BE MODIFIED TO IMPLEMENT MULTI-PORT
- ; OPERATION.
- ;
- READ: MOV AX,BUFCNT
- CMP AX,0
- JE NOCHARS
- DEC BUFCNT ; REDUCE NUMBER OF CHARS IN BUFFER
- MOV SI,SVADR ; GET OUR CURRENT ADR IN BUFFER
- MOV AL,BYTE PTR[SI] ; GET CHARACTER
- INC SI
- CMP SI,OFFSET LADR ; AT LAST ADDR ?
- JNE CONT
- MOV SI,OFFSET INBUF
- CONT: MOV SVADR,SI ; SAVE CURRENT INPUT BUFFER ADDRESS
- NOCHARS:JMP COMEXIT ; CHAR SHOULD BE IN AL
- ;************************ WRITE CHAR IN DL **************************
- ;
- WRITE:
- MOV AH,DL
- MOV DX,ACOM
- TXIP: IN AL,DX ; DONT TRANSMIT IF ALREADY TRANSMITTING
- AND AL,4
- JZ TXIP
- MOV DX,ADAT
- MOV AL,AH
- OUT DX,AL ; OUTPUT CHAR
- XOR AX,AX
- JMP COMEXIT
- ;***************** ISSUE BREAK ***********************
- BRAAK:
- MOV AL,5 ; WR5
- MOV DX,ACOM
- OUT DX,AL
- MOV AL,0FAH ; BREAK ENABLE BIT
- OUT DX,AL
- MOV CX,7F00H ; WAIT A WHILE
- WAITX:
- PUSH CX
- NOP
- POP CX
- LOOP WAITX
- MOV AL,0EAH ; DISABLE BREAK BIT
- PUSH AX
- MOV AL,5
- OUT DX,AL ; WR5
- POP AX
- OUT DX,AL ; KILL BREAK
- JMP COMEXIT
- ;********************* CLOSE PORT ***********************
- CLOSE:
- MOV DX,ACOM
- MOV AL,9 ; WR9
- OUT DX,AL
- MOV AL,RESET
- OUT DX,AL
- MOV AL,37H
- OUT 19H,AL ; DISABLE 8259 IR0
- JMP COMEXIT
- ;********************* BUFFER PURGE **********************
- PURGE:
- XOR AX,AX
- MOV BUFCNT,AX
- MOV AX,OFFSET INBUF
- MOV SVADR,AX
- MOV INADR,AX
- JMP COMEXIT
- ;************************** END OF SVC SERVICE CODE *********************
- ;******************** START OF 8530 INTERRUPT SERVICE CODE ***************
- DSADDR EQU 180H
- INTCTR EQU 19AH
- STKSAV DW 0
- DW 0
- DW 50 DUP(0) ; RESERVE SOME INTERNAL STACK
- INTSTK LABEL WORD
- ERRST DW 0
- COMISR: ; INTERRUPTS DISABLED THROUGHOUT
- PUSH DS
- CLI
- MOV CS:STKSAV+2,SS
- MOV CS:STKSAV,SP
- MOV SP,CS
- MOV SS,SP
- MOV SP,OFFSET INTSTK
- PUSH AX
- XOR AX,AX
- MOV DS,AX
- INC DS:BYTE PTR[INTCTR] ; ADD 1 TO INTERRUPT COUNT
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH CS
- POP DS
- NEXT: MOV DX,CINT ; INTERRUPT ACKNOWLEDGE PORT
- MOV AL,0
- OUT DX,AL
- IN AL,DX ; ACKNOWLEDGE INTERRUPT
- MOV DX,ACOM ;
- IN AL,DX ; GET STATUS
- AND AL,1
- JE NODATA
- MOV DX,ADAT
- IN AL,DX ; READ DATA
- MOV BX,BUFCNT ; GET CURRENT DATA IN BUFFER LENGTH
- MOV CX,ERRST ; CHECK IF WE ARE DISCARDING
- JCXZ NODISC
- CMP BX,0
- JNE DISMOR ; NON 0 MEANS KEEP DISCARDING
- XOR BX,BX ; CLEAR DISCARD FLAG
- MOV ERRST,BX
-
- NODISC:
- MOV CX,BX
- JCXZ CLEAR
- MOV BX,INADR ; 8530'S CURRENT ADR
- CMP BX,SVADR ; IF = THEN BUFFER OVERFLOW
- JE BOVF
- CLEAR: MOV BX,INADR
- MOV BYTE PTR[BX],AL ; SAVE CHAR IN BUFFER
- INC BUFCNT
- INC BX
- CMP BX,OFFSET LADR ; CHECK IF LAST ADDR IN BUFFER
- JNE NOTLAS
- DISMOR: MOV BX,OFFSET INBUF ; RESET INPUT POINTER
- NOTLAS: MOV INADR,BX
- NODATA: MOV DX,ACOM
- MOV AL,38H
- OUT DX,AL ; RESET HIGHEST IUS IN 8530
- IN AL,DX ; CHECK IF MORE CHARS IN 8530'S BUFFER
- AND AL,1
- JNZ NEXT ; DUE TO THE OVERHEAD INVOLVED IN INTERRUPTING
- POP DX ; IT IS PROBBABLE THAT MORE THAN 1 CHAR
- POP CX ; MAY BE IN THE 8530, IT IS CHEAPER IN CLOCK CYCLES
- POP BX ; FOR US TO READ ALL CHARS UNTIL THE 8530
- MOV AL,20H ; HAS NO MORE.(ALIAS: KILL 2 STONES WITH 1 BIRD)
- OUT 18H,AL ; RESET TO 8259
- XOR AX,AX
- MOV DS,AX
- DEC DS:BYTE PTR[INTCTR] ; UPDATE INTERRUPT COUNT
- POP AX
- MOV SP,CS:[STKSAV+2]
- MOV SS,SP
- MOV SP,CS:[STKSAV] ; RESTORE CALLERS STACK
- POP DS
- IRET ;
- BOVF:
- MOV AX,0
- MOV BUFCNT,AX
- INC AX
- MOV ERRST,AX ; SET DISCARD FLAG
- JMP NODATA ; GO BACK
-
- ;********************** END OF 8530 ISR *****************************
- BUFLEN EQU 0D000H ; 32K CURRENTLY
- INBUF:
- DB BUFLEN DUP(0); INPUT BUFFER
- LADR:
- EOMOD: ; LAST ADDRESS SAVED AFTER TERMINATION
-
- BADMSG DB ' INVALID OPTION, ENTER "TICOM/T" TO TERMINATE'
- DB ' OR "TICOM" TO LOAD ',0DH,0AH,'$'
- NRMSG DB ' TICOM NOT RESIDENT..IGNORED',0DH,0AH,'$'
- NTERM DB ' TICOM DISABLED, MEMORY FREED',0DH,0AH,'$'
- STMSG DB ' TI-COM RESIDENT COMMUNICATIONS PACKAGE ',0DH,0AH
- DB ' UNCOPYRIGHT(U) 1986 DAN MAUS',0DH,0AH
- DB ' REVISION 1.0 ',0DH,0AH,'$'
- LDMSG DB ' LOADED USING INTERRUPTS 40H(8259 IR0), & 70H(SVC)',0DH,0AH,'$'
- INMSG DB ' ALREADY RESIDENT ',0DH,0AH,'$'
-
-
-
- ;********************* START UP CODE **************************
- START:
- PUSH CS
- POP DS
- MOV DX, OFFSET STMSG
- MOV AH,09H
- INT 21H
- MOV AL, BYTE PTR ES:[COMNLEN]
- CMP AL,0
- JE LOADIT ; NO PARAMETER MEANS LOAD & KEEP PROCESS
- ; TERMINATE IF IN CORE OTHERWISE TELL NOT IN CORE
- MOV AX, WORD PTR ES:[COMNLEN+1]
- CMP AX,'T/' ; CHECK FOR /T TO VERIFY TERMINATION
- JNE BADCMD
- MOV AH,35H ; GET VECTOR
- MOV AL,COMINT
- INT 21H
- CMP BX,OFFSET COMISR
- JNE NOTRES ; NOT LOADED OR VECTOR CORRUPTION
-
- LDS DX,SVCOLD ; OLD SVCINT VECTOR
- MOV AH,25H
- MOV AL,SVCINT ; RESTORE SVCINT VECTOR
- INT 21H
- LDS DX,COMOLD ; OLD 8530 INTERRUPT VECTOR
- MOV AL,COMINT
- INT 21H
- MOV AX,ES
- SUB AX,10H ; MAKE PSP ADJUSTMENT
- MOV ES,AX
- MOV AH,49H ; AT THIS POINT ES: SHOULD BE OUR BLOCK
- INT 21H ; DEALLOCATE
- PUSH CS
- POP DS
- MOV DX, OFFSET NTERM ; NORMAL TERMINATION MESSAGE
- EXIT: MOV AH,09H
- INT 21H
- MOV AH,4CH ; TERMINATE NORMAL(NO KEEP PROCESS)
- INT 21H
- BADCMD: MOV DX, OFFSET BADMSG ; INVALID CONTROL '/T' ONLY VALID
- JMP EXIT
- NOTRES: MOV DX, OFFSET NRMSG ; NOT RESIDENT MESSAGE
- JMP EXIT
- INMEM: MOV DX, OFFSET INMSG ; ALREADY RESIDENT ERROR
- JMP EXIT
- LOADIT: ; SET INTERRUPT VECTORS
- ; AND KEEP PROCESS
- PUSH DS
- POP ES
- PUSH ES
- MOV AL,COMINT
- MOV AH,35H ; GET VECTOR
- INT 21H
- CMP BX,OFFSET COMISR
- JE INMEM ; CHECK IF ALREADY IN MEMORY
- MOV COMOLD,BX
- MOV BX,ES ; SAVE OLD SVC VECTOR
- MOV COMOLD+2,BX
- MOV AL,SVCINT
- INT 21H
- MOV SVCOLD,BX
- MOV BX,ES ; SAVE OLD COMINT VECTOR
- MOV SVCOLD+2,BX
- POP ES
- MOV AH,25H
- MOV DX, OFFSET SVCISR ; SET SVC VECTOR
- MOV AL, SVCINT
- INT 21H
- MOV DX, OFFSET COMISR ; SET COMINT VECTOR
- MOV AL, COMINT
- INT 21H
- MOV DX, OFFSET LDMSG
- MOV AH,09H
- INT 21H
- MOV AH,31H ; KEEP PROCESS
- MOV DX,OFFSET EOMOD ; LAST LOCATION
- ADD DX,110H ; ; ACCOUNT FOR PSP & LAST PARAGRAPH
- SHR DX,1 ;
- SHR DX,1
- SHR DX,1
- SHR DX,1 ; MAKE INTO PARAGRAPHS
- INT 21H ; TERMINATE & STAY RESIDENT (2.1 TYPE)
- CODE ENDS
- END